<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	<meta name="author" content="The CSS Ninja" />
	<meta name="keywords" content="Css, CSS Ninja, The CSS Ninja, JavaScript, Web, xhtml, html, browsers, HTML5, CSS3" />
	<meta name="description" content="Using drag drop API, File API and XmlHttpRequest 2 to create a drag and drop upload system using only JavaScript" />
	<meta name="robots" content="all" />
	<meta name="copyright" content="The CSS Ninja" />
	
	<link rel="stylesheet" type="text/css" href="_styles.css" media="screen" />
	
	<script type="text/javascript">
		var TCNDDU = TCNDDU || {};
		
		(function(){
			var dropContainer,
				dropListing,
				imgPreviewFragment = document.createDocumentFragment(),
				domElements;
			
			TCNDDU.setup = function () {
				dropListing = document.getElementById("output-listing01");
				dropContainer = document.getElementById("output");
				
				dropContainer.addEventListener("dragenter", function(event){dropListing.innerHTML = '';event.stopPropagation();event.preventDefault();}, false);
				dropContainer.addEventListener("dragover", function(event){event.stopPropagation();event.preventDefault();}, false);
				dropContainer.addEventListener("drop", TCNDDU.handleDrop, false);
			};
			
			/*TCNDDU.uploadProgressXHR = function (event) {
				if (event.lengthComputable) {
					var percentage = Math.round((event.loaded * 100) / event.total),
						loaderIndicator = event.target.log.firstChild.nextSibling.firstChild;
						console.log(loaderIndicator);
						console.log(event.target.self);
						console.log(event.target);
					if (percentage < 100) {
						loaderIndicator.style.width = (percentage*2) + "px";
						loaderIndicator.textContent = percentage + "%";
					}
				}
			};
			
			TCNDDU.loadedXHR = function (event) {
				var currentImageItem = event.target.log;
				
				currentImageItem.className = "loaded";
				console.log("xhr upload of "+event.target.log.id+" complete");
			};*/
			
			TCNDDU.uploadError = function (error) {
				console.log("error: " + error.code);
			};
			
			TCNDDU.processXHR = function (file, index, bin) {
				var xhr = new XMLHttpRequest(),
					container = document.getElementById("item"+index),
					fileUpload = xhr.upload,
					progressDomElements = [
						document.createElement('div'),
						document.createElement('p')
					];
				
				progressDomElements[0].className = "progressBar";
				progressDomElements[1].textContent = "0%";
				progressDomElements[0].appendChild(progressDomElements[1]);
				
				container.appendChild(progressDomElements[0]);
				
				fileUpload.log = container;
				
				fileUpload.addEventListener("progress", function(event) {
					if (event.lengthComputable) {
						var percentage = Math.round((event.loaded * 100) / event.total),
						loaderIndicator = container.firstChild.nextSibling.firstChild;
						if (percentage < 100) {
							loaderIndicator.style.width = (percentage*2) + "px";
							loaderIndicator.textContent = percentage + "%";
						}
					}
				}, false);
				
				fileUpload.addEventListener("load", function(event) {
					container.className = "loaded";
					console.log("xhr upload of "+container.id+" complete");
				}, false);
				
				fileUpload.addEventListener("error", TCNDDU.uploadError, false);

				xhr.open("POST", "../upload.php");
				xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
				xhr.sendAsBinary(bin)
			};
			
			TCNDDU.handleDrop = function (event) {
				var dt = event.dataTransfer,
					files = dt.files,
					count = files.length;
				
				event.stopPropagation();
				event.preventDefault();

				for (var i = 0; i < count; i++) {
					if(files[i].size < 1048576) {
						var file = files[i],
							droppedFileName = file.name,
							reader = new FileReader();
							reader.index = i;
							reader.file = file;
						
						reader.addEventListener("loadend", TCNDDU.buildImageListItem, false);
						reader.readAsDataURL(file);
					} else {
						alert("file is too big, needs to be below 1mb");
					}
				}
			};
			
			TCNDDU.buildImageListItem = function (event) {
				domElements = [
					document.createElement('li'),
					document.createElement('a'),
					document.createElement('img'),
					document.createElement('p')
				];
			
				var data = event.target.result,
					index = event.target.index,
					file = event.target.file,
					getBinaryDataReader = new FileReader();
				
				domElements[2].src = data // base64 encoded string of local file(s)
				domElements[2].width = 300;
				domElements[2].height = 200;
				domElements[1].appendChild(domElements[2]);
				domElements[0].id = "item"+index;
				domElements[0].appendChild(domElements[1]);
				
				imgPreviewFragment.appendChild(domElements[0]);
				
				dropListing.appendChild(imgPreviewFragment);
				
				getBinaryDataReader.addEventListener("loadend", function(evt){TCNDDU.processXHR(file, index, evt.target.result);}, false);
				getBinaryDataReader.readAsBinaryString(file);
			};
			
			window.addEventListener("load", TCNDDU.setup, false);
		})();
	</script>
	
	<title>Using the File API to upload files by dragging and dropping from desktop | The CSS Ninja</title>

</head>
<body>
	
	<div id="output" class="clearfix">
		<ul id="output-listing01"></ul>
	</div>
	
</body>
</html>
